home *** CD-ROM | disk | FTP | other *** search
- /*
- File: Orbits.c
-
- Contains: Planetary orbit display templates
-
- Written by: Harry Chesley
-
- Copyright: © 1994 by Apple Computer, Inc.
-
- Change History (most recent first):
-
- 5/25/94 hrc created
-
- To Do:
- */
-
- #include <SANE.h>
- #include <String.h>
- #include <Packages.h>
- #include <Script.h>
- #include <OSUtils.h>
- #include <Math.h>
- #include <Quickdraw.h>
- #include <TextUtils.h>
- #include "OCETemplates.h"
- #include "Orbits.h"
-
- OSErr instanceInit(DETCallBlockPtr);
- OSErr idle(DETCallBlockPtr);
- OSErr convertToRString(DETCallBlockPtr);
- OSErr convertFromRString(DETCallBlockPtr);
- OSErr propertyDirtied(DETCallBlockPtr);
- OSErr updateOrbitEntries(DETCallBlockPtr);
- OSErr customViewDraw(DETCallBlockPtr);
-
- unsigned long getNumberProperty(DETCallBlockPtr, short);
- extended getExtendedProperty(DETCallBlockPtr, short);
- LongDateTime getTimeProperty(DETCallBlockPtr, short);
- OSErr setSublistTimeProperty(DETCallBlockPtr, short property, long itemNumber, LongDateTime);
-
- pascal OSErr Orbits(DETCallBlockPtr callBlockPtr)
- {
- if (callBlockPtr->protoCall.target.selector == kDETSelf)
- switch (callBlockPtr->protoCall.reqFunction)
- {
- case kDETcmdInstanceInit: return instanceInit(callBlockPtr);
- case kDETcmdIdle: return idle(callBlockPtr);
- case kDETcmdConvertToRString: return convertToRString(callBlockPtr);
- case kDETcmdConvertFromRString: return convertFromRString(callBlockPtr);
- case kDETcmdPropertyDirtied: return propertyDirtied(callBlockPtr);
- case kDETcmdCustomViewDraw: return customViewDraw(callBlockPtr);
- }
-
- else if (callBlockPtr->protoCall.reqFunction == kDETcmdInit)
- {
- callBlockPtr->init.newCallFors = kDETCallForIdle + kDETCallForViewChanges;
- return noErr;
- }
-
- return kDETDidNotHandle;
- }
-
- void setTimeToNow(DETCallBlockPtr callBlockPtr)
- {
- unsigned long l;
- LongDateTime ldt, oldLdt;
- DETSetPropertyBinaryBlock spb;
-
- // Get the old time
- oldLdt = getTimeProperty(callBlockPtr, kOrbitsTimeProperty);
- // Get the current time
- GetDateTime(&l);
- ldt = l;
- // Only change if it's different
- if (ldt != oldLdt)
- {
- // Set the property value
- spb.reqFunction = kDETcmdSetPropertyBinary;
- spb.target = callBlockPtr->protoCall.target;
- spb.property = kOrbitsTimeProperty;
- spb.newValue = (Ptr) &ldt;
- spb.newValueSize = sizeof(ldt);
- if (CallBackDET(callBlockPtr, (DETCallBackBlock*) &spb) == noErr)
- {
- // Dirty the property (force updates)
- DETDirtyPropertyBlock dp;
-
- dp.reqFunction = kDETcmdDirtyProperty;
- dp.target = callBlockPtr->protoCall.target;
- dp.property = kOrbitsTimeProperty;
- CallBackDET(callBlockPtr, (DETCallBackBlock*) &dp);
- dp.property = kOrbitsCustomViewProperty;
- CallBackDET(callBlockPtr, (DETCallBackBlock*) &dp);
- }
- }
- }
-
- OSErr instanceInit(DETCallBlockPtr callBlockPtr)
- {
- // Set the time property type
- DETSetPropertyTypeBlock spt;
-
- spt.reqFunction = kDETcmdSetPropertyType;
- spt.target = callBlockPtr->protoCall.target;
- spt.property = kOrbitsTimeProperty;
- spt.newType = kTimePropertyType;
- CallBackDET(callBlockPtr, (DETCallBackBlock*) &spt);
-
- setTimeToNow(callBlockPtr);
-
- return noErr;
- }
-
- OSErr idle(DETCallBlockPtr callBlockPtr)
- {
- // Update time if requested
- if (getNumberProperty(callBlockPtr, kOrbitsNowProperty)) setTimeToNow(callBlockPtr);
- return noErr;
- }
-
- OSErr convertToRString(DETCallBlockPtr callBlockPtr)
- {
- DETConvertToRStringBlock* ctrs;
- DETGetPropertyTypeBlock gpt;
-
- ctrs = &(callBlockPtr->convertToRString);
-
- // Get the type of the property being converted
- gpt.reqFunction = kDETcmdGetPropertyType;
- gpt.target = ctrs->target;
- gpt.property = ctrs->property;
- if (CallBackDET(callBlockPtr, (DETCallBackBlock*) &gpt) == noErr)
- {
- char s[256];
- RStringHandle h;
-
- // Convert time properties
- if (gpt.propertyType == kTimePropertyType)
- {
- LongDateTime ldt;
- char tStr[256];
-
- // Get the current value
- ldt = getTimeProperty(callBlockPtr, ctrs->property);
-
- // Convert it to a string
- iuldatestring(&ldt, shortDate, s, nil);
- tStr[0] = ' ';
- tStr[1] = 0;
- strcat(s, tStr);
- iultimestring(&ldt, true, tStr, nil);
- strcat(s, tStr);
- }
-
- else return kDETDidNotHandle;
-
- // Return the string as an RString handle
- h = (RStringHandle) NewHandle(strlen(s) + sizeof(ProtoRString));
- if (h)
- {
- HLock((Handle) h);
- OCECToRString(s, smRoman, *h, strlen(s));
- HUnlock((Handle) h);
- ctrs->theValue = h;
-
- return noErr;
- }
- else return MemError();
- }
-
- return kDETDidNotHandle;
- }
-
- OSErr convertFromRString(DETCallBlockPtr callBlockPtr)
- {
- OSErr retVal;
- DETConvertFromRStringBlock* cfrs;
- DETGetPropertyTypeBlock gpt;
-
- retVal = kDETDidNotHandle;
- cfrs = &(callBlockPtr->convertFromRString);
-
- // Get the property type to convert
- gpt.reqFunction = kDETcmdGetPropertyType;
- gpt.target = cfrs->target;
- gpt.property = cfrs->property;
- if (CallBackDET(callBlockPtr, (DETCallBackBlock*) &gpt) == noErr)
- {
- char* str;
-
- // Convert the RString into a string
- str = ((char*) &cfrs->theValue->dataLength) + 1;
- p2cstr(str);
-
- // Convert time properties
- if (gpt.propertyType == kTimePropertyType)
- {
- DateCacheRecord dc;
-
- // Init the date cache
- if (InitDateCache(&dc) == noErr)
- {
- long lengthUsed;
- LongDateRec ldr;
- LongDateTime ldt;
- long strLength;
- DETSetPropertyBinaryBlock spb;
-
- // Convert the string to a time
- strLength = strlen(str);
- String2Date(str, strLength, &dc, &lengthUsed, &ldr);
- if ((strLength - lengthUsed) <= 0)
- {
- ldr.ld.hour = 0;
- ldr.ld.minute = 0;
- ldr.ld.second = 0;
- }
- else String2Time(str + lengthUsed, strLength - lengthUsed, &dc, &lengthUsed, &ldr);
- LongDate2Secs(&ldr, &ldt);
-
- // Set the property value
- spb.reqFunction = kDETcmdSetPropertyBinary;
- spb.target = cfrs->target;
- spb.property = cfrs->property;
- spb.newValue = (Ptr) &ldt;
- spb.newValueSize = sizeof(ldt);
- if (CallBackDET(callBlockPtr, (DETCallBackBlock*) &spb) == noErr)
- {
- // Mark it as changed
- DETSetPropertyChangedBlock spc;
- spc.reqFunction = kDETcmdSetPropertyChanged;
- spc.target = cfrs->target;
- spc.property = cfrs->property;
- spc.propertyChanged = true;
- CallBackDET(callBlockPtr, (DETCallBackBlock*) &spc);
- }
-
- retVal = noErr;
- }
- }
-
- c2pstr(str);
- }
-
- return retVal;
- }
-
- OSErr propertyDirtied(DETCallBlockPtr callBlockPtr)
- {
- DETPropertyDirtiedBlock* pd;
-
- // Check if we're interested in this property
- pd = (DETPropertyDirtiedBlock*) &callBlockPtr->propertyDirtied;
- switch (pd->property)
- {
- case kOrbitsTimeProperty:
- updateOrbitEntries(callBlockPtr);
- return noErr;
- }
-
- return kDETDidNotHandle;
- }
-
- OSErr updateOrbitEntries(DETCallBlockPtr callBlockPtr)
- {
- LongDateTime ldt;
- long i;
-
- // Get the time from the time field
- ldt = getTimeProperty(callBlockPtr, kOrbitsTimeProperty);
-
- // Set the time in each sublist entry
- for (i = 1;; i++)
- if (setSublistTimeProperty(callBlockPtr, kTimeProperty, i, ldt) != noErr) break;
-
- return noErr;
- }
-
- unsigned long getNumberProperty(DETCallBlockPtr callBlockPtr, short property)
- {
- DETGetPropertyNumberBlock gpn;
-
- gpn.reqFunction = kDETcmdGetPropertyNumber;
- gpn.target = callBlockPtr->protoCall.target;
- gpn.property = property;
- if (CallBackDET(callBlockPtr, (DETCallBackBlock*) &gpn) != noErr) return 0;
-
- return gpn.propertyValue;
- }
-
- extended getExtendedProperty(DETCallBlockPtr callBlockPtr, short property)
- {
- DETGetPropertyBinaryBlock gpb;
- extended n;
-
- gpb.reqFunction = kDETcmdGetPropertyBinary;
- gpb.target = callBlockPtr->protoCall.target;
- gpb.property = property;
- if (CallBackDET(callBlockPtr, (DETCallBackBlock*) &gpb) != noErr) return 0.0;
-
- BlockMove(*gpb.propertyValue, (char*) &n, sizeof(n));
- DisposHandle(gpb.propertyValue);
-
- return n;
- }
-
- LongDateTime getTimeProperty(DETCallBlockPtr callBlockPtr, short property)
- {
- DETGetPropertyBinaryBlock gpb;
- LongDateTime ldt;
-
- gpb.reqFunction = kDETcmdGetPropertyBinary;
- gpb.target = callBlockPtr->protoCall.target;
- gpb.property = property;
- if (CallBackDET(callBlockPtr, (DETCallBackBlock*) &gpb) != noErr) return 0;
-
- BlockMove(*gpb.propertyValue, (char*) &ldt, sizeof(ldt));
- DisposHandle(gpb.propertyValue);
-
- return ldt;
- }
-
- OSErr setSublistTimeProperty(DETCallBlockPtr callBlockPtr, short property, long itemNumber, LongDateTime ldt)
- {
- DETSetPropertyBinaryBlock spb;
- OSErr retVal;
-
- spb.reqFunction = kDETcmdSetPropertyBinary;
- spb.target.selector = kDETSublistItem;
- spb.target.aspectName = nil;
- spb.target.itemNumber = itemNumber;
- spb.property = property;
- spb.newValue = (Ptr) &ldt;
- spb.newValueSize = sizeof(ldt);
- retVal = CallBackDET(callBlockPtr, (DETCallBackBlock*) &spb);
- if (retVal == noErr)
- {
- DETDirtyPropertyBlock dp;
-
- dp.reqFunction = kDETcmdDirtyProperty;
- dp.target.selector = kDETSublistItem;
- dp.target.aspectName = nil;
- dp.target.itemNumber = itemNumber;
- dp.property = kOrbitsTimeProperty;
- retVal = CallBackDET(callBlockPtr, (DETCallBackBlock*) &dp);
- }
-
- return retVal;
- }
-
- OSErr getSublistExtendedProperty(DETCallBlockPtr callBlockPtr, long itemNumber, short property, extended* n)
- {
- DETGetPropertyBinaryBlock gpb;
- OSErr retVal;
-
- gpb.reqFunction = kDETcmdGetPropertyBinary;
- gpb.target.selector = kDETSublistItem;
- gpb.target.aspectName = nil;
- gpb.target.itemNumber = itemNumber;
- gpb.property = property;
- retVal = CallBackDET(callBlockPtr, (DETCallBackBlock*) &gpb);
- if (retVal != noErr) return retVal;
- BlockMove(*gpb.propertyValue, (char*) n, sizeof(*n));
-
- return noErr;
- }
-
- OSErr getSublistPosition(DETCallBlockPtr callBlockPtr, long itemNumber, LongDateTime ldt, extended* x, extended* y)
- {
- DETGetPropertyBinaryBlock gpb;
- OSErr retVal;
-
- // Set the time
- retVal = setSublistTimeProperty(callBlockPtr, kTimeProperty, itemNumber, ldt);
- if (retVal != noErr) return retVal;
-
- // Get x
- retVal = getSublistExtendedProperty(callBlockPtr, itemNumber, kXProperty, x);
- if (retVal != noErr) return retVal;
-
- // Get y
- gpb.property = kYProperty;
- retVal = getSublistExtendedProperty(callBlockPtr, itemNumber, kYProperty, y);
- if (retVal != noErr) return retVal;
-
- return noErr;
- }
-
- OSErr customViewDraw(DETCallBlockPtr callBlockPtr)
- {
- DETGetCustomViewBoundsBlock gcvb;
- OSErr retVal;
- DETGetPropertyRStringBlock gpr;
- long showOrbits;
- LongDateTime ldt;
- short halfWidth, halfHeight, centerX, centerY;
- extended x, y;
- extended largestDistance;
- extended scaleFactor;
- long i;
- Rect r;
-
- // If this isn't for our view, then ignore it
- if (callBlockPtr->protoCall.property != kOrbitsCustomViewProperty) return kDETDidNotHandle;
-
- // Get the bounds of the view
- gcvb.reqFunction = kDETcmdGetCustomViewBounds;
- gcvb.target = callBlockPtr->protoCall.target;
- gcvb.property = callBlockPtr->protoCall.property;
- retVal = CallBackDET(callBlockPtr, (DETCallBackBlock*) &gcvb);
- if (retVal != noErr) return retVal;
-
- // Figure the center
- halfWidth = (gcvb.bounds.right - gcvb.bounds.left) / 2;
- halfHeight = (gcvb.bounds.bottom - gcvb.bounds.top) / 2;
- centerX = gcvb.bounds.left + halfWidth;
- centerY = gcvb.bounds.top + halfHeight;
-
- // Draw space
- PaintRect(&gcvb.bounds);
-
- // Draw the sun
- ForeColor(whiteColor);
- r.top = centerY - 4; r.bottom = centerY + 4;
- r.left = centerX - 4; r.right = centerX + 4;
- PaintOval(&r);
-
- // Get the time
- ldt = getTimeProperty(callBlockPtr, kOrbitsTimeProperty);
-
- // Guess the max size
- largestDistance = 0.0;
- for (i = 1;; i++)
- {
- extended newDistance;
- if (getSublistPosition(callBlockPtr, i, ldt, &x, &y) != noErr) break;
- newDistance = sqrt(x*x + y*y);
- if (newDistance > largestDistance) largestDistance = newDistance;
- }
- scaleFactor = (halfHeight - 15) / largestDistance;
-
- // Plot everyone
- showOrbits = getNumberProperty(callBlockPtr, kOrbitsCustomViewProperty);
- TextFont(kDETApplicationFont);
- TextSize(9);
- gpr.reqFunction = kDETcmdGetPropertyRString;
- gpr.target.selector = kDETSublistItem;
- gpr.target.aspectName = nil;
- gpr.property = kDETPrName;
- for (i = 1;; i++)
- {
- // Draw the body
- if (getSublistPosition(callBlockPtr, i, ldt, &x, &y) != noErr) break;
- r.top = centerY - ((short) rint(scaleFactor*y)) - 1; r.bottom = r.top + 3;
- r.left = centerX + ((short) rint(scaleFactor*x)) - 1; r.right = r.left + 3;
- PaintOval(&r);
-
- // Draw the name
- gpr.target.itemNumber = i;
- if ((CallBackDET(callBlockPtr, (DETCallBackBlock*) &gpr) == noErr) && ((*gpr.propertyValue)->dataLength < 256))
- {
- HLock((Handle) gpr.propertyValue);
- MoveTo(r.right + 1, r.top < centerY ? r.top - 1 : r.bottom + 10);
- DrawString(((char*) &(*gpr.propertyValue)->dataLength) + 1);
- DisposHandle((Handle) gpr.propertyValue);
- }
-
- // Show the future track (if requested)
- if (showOrbits)
- {
- LongDateTime ldtInc;
- extended orbitInc;
- short j;
-
- if (getSublistExtendedProperty(callBlockPtr, i, kTpProperty, &orbitInc) != noErr) break;
- // orbitInc is calculated such that 36 of them will produce a
- // complete one year orbit
- orbitInc *= (10.0*24.0*60.0*60.0);
- for (j = 36, ldtInc = ldt + orbitInc; j--; ldtInc += orbitInc)
- {
- if (getSublistPosition(callBlockPtr, i, ldtInc, &x, &y) != noErr) break;
- r.left = centerX + ((short) rint(scaleFactor*x)); r.right = r.left + 1;
- r.top = centerY - ((short) rint(scaleFactor*y)); r.bottom = r.top + 1;
- PaintRect(&r);
- }
- }
- }
-
- // Return things to normal
- ForeColor(blackColor);
- updateOrbitEntries(callBlockPtr);
-
- return noErr;
- }
-